/*
 * #%L
 * SwiftUICommonUtilities
 * $Id:$
 * $HeadURL:$
 * %%
 * Copyright (C) 2011 - 2012 Linkwithweb
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */
/**
 * 
 */
package com.linkwithweb.products.swiftui.freemarker;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;

import com.linkwithweb.products.swiftui.context.SystemContext;

import freemarker.cache.URLTemplateLoader;

/**
 * 
 * Custom Page loader which is used to load app specific pages...
 * 
 * @author ashwin kumar
 * 
 */
public class SwiftUIFreemarkerTemplateLoader extends URLTemplateLoader {
	private Class loaderClass;
	private String path;

	public SwiftUIFreemarkerTemplateLoader() {
		super();
		setFields(this.getClass(), "templates");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * freemarker.cache.URLTemplateLoader#findTemplateSource(java.lang.String)
	 */
	public Object findTemplateSource(String name) throws IOException {
		String appId = SystemContext.getInstance().getUserContext().getIdentifier();
		appId = canonicalizePrefix(appId);

		URL url = getURL(appId + name);

		if (url == null)
			url = getURL(name);

		return url == null ? null : new URLTemplateSource(url);
	}

	protected URL getURL(String name) {
		return loaderClass.getResource(path + name);
	}

	/**
	 * Given a template name (plus potential locale decorations) retrieves
	 * an URL that points the template source.
	 * 
	 * @param name
	 *            the name of the sought template, including the locale
	 *            decorations.
	 * @return an URL that points to the template source, or null if it can
	 *         determine that the template source does not exist.
	 */

	public long getLastModified(Object templateSource) {
		return ((URLTemplateSource) templateSource).lastModified();
	}

	public Reader getReader(Object templateSource, String encoding) throws IOException {
		return new InputStreamReader(((URLTemplateSource) templateSource).getInputStream(), encoding);
	}

	public void closeTemplateSource(Object templateSource) throws IOException {
		((URLTemplateSource) templateSource).close();
	}

	/**
	 * Can be used by subclasses to canonicalize URL path prefixes.
	 * 
	 * @param prefix
	 *            the path prefix to canonicalize
	 * @return the canonicalized prefix. All backslashes are replaced with
	 *         forward slashes, and a trailing slash is appended if the original
	 *         prefix wasn't empty and didn't already end with a slash.
	 */
	protected static String canonicalizePrefix(String prefix) {
		// make it foolproof
		prefix = prefix.replace('\\', '/');
		// ensure there's a trailing slash
		if (prefix.length() > 0 && !prefix.endsWith("/")) {
			prefix += "/";
		}
		return prefix;
	}

	private void setFields(Class loaderClass, String path) {
		if (loaderClass == null) {
			throw new IllegalArgumentException("loaderClass == null");
		}
		if (path == null) {
			throw new IllegalArgumentException("path == null");
		}
		this.loaderClass = loaderClass;
		this.path = canonicalizePrefix(path);
	}
}
